package com.xhh.hybriddemo.common;

import android.content.Context;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 异常处理
 */
public class AppExceptionHandler implements Thread.UncaughtExceptionHandler {

    private static AppExceptionHandler mInstance = new AppExceptionHandler();

    private Thread.UncaughtExceptionHandler mDefaultHandler;

    private DateFormat mDateFormat = new SimpleDateFormat("MM-dd-HH-mm-ss-SSS");

    private Context mContext;

    private AppExceptionHandler() {
    }

    public static AppExceptionHandler getInstance() {
        return mInstance;
    }

    public void init(Context context) {
        mContext = context;
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        Log.e("Crash", "ERROR", ex);
        if (!handleException(ex) && mDefaultHandler != null) {
            mDefaultHandler.uncaughtException(thread, ex);
        } else {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Log.w("Crash", e);
            }
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        }
    }

    private boolean handleException(Throwable ex) {
        if (ex == null) {
            return false;
        }

        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(mContext, "很抱歉，系统出现异常，即将退出", Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();

        saveLog(ex);

        return true;
    }

    private void saveLog(Throwable ex) {

        StringBuilder sb = new StringBuilder();
        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = ex.getCause();
        }
        printWriter.close();

        String result = writer.toString();
        sb.append(result);

        String filename = "hqd-" + mDateFormat.format(new Date());

        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            String path = "/sdcard/crash";
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            try {
                FileOutputStream fos = new FileOutputStream(new File(dir, filename));
                fos.write(sb.toString().getBytes());
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}
